home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DJGPP / BNU22SR1.ZIP / src / binutils.2 / bfd / cpu-h830.c < prev    next >
C/C++ Source or Header  |  1993-05-30  |  10KB  |  442 lines

  1. /* BFD library support routines for the Hitachi H8/300 architecture.
  2.    Copyright (C) 1990-1991 Free Software Foundation, Inc.
  3.    Hacked by Steve Chamberlain of Cygnus Support.
  4.  
  5. This file is part of BFD, the Binary File Descriptor library.
  6.  
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or
  10. (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  20.  
  21. #include "bfd.h"
  22. #include "sysdep.h"
  23. #include "libbfd.h"
  24.  
  25. #define DEFINE_TABLE 
  26. #include "opcode/h8300.h"
  27.  
  28. #define MAXSAME 14
  29.  
  30. static struct h8_opcode * h8_opcodes_sorted[256][MAXSAME];
  31.  
  32. /* Run through the opcodes and sort them into order to make them easy
  33.    to disassemble
  34.  */
  35. static void
  36. DEFUN_VOID(bfd_h8_disassemble_init)
  37. {
  38.   unsigned int i;    
  39.   struct h8_opcode *p; 
  40.     
  41.   for (p = h8_opcodes; p->name; p++) {    
  42.     int n1 = 0;
  43.     int n2 = 0;
  44.  
  45.     if ((int)p->data.nib[0] < 16) {
  46.       n1 =(int) p->data.nib[0] ;
  47.     } else n1 = 0;
  48.     if ((int)p->data.nib[1] < 16) {
  49.       n2 = (int) p->data.nib[1];
  50.     }else n2 = 0;
  51.  
  52.     for (i = 0; i < MAXSAME; i++) {
  53.       int j = n1 * 16 + n2;
  54.       if (h8_opcodes_sorted[j][i] == (struct h8_opcode *)NULL) {
  55.     h8_opcodes_sorted[j][i] = p;
  56.     break;
  57.       }
  58.     }
  59.     
  60.     if (i==MAXSAME)abort();
  61.  
  62.     /* Just make sure there are an even number of nibbles in it, and
  63.        that the count is the same s the length */
  64.     for (i = 0; p->data.nib[i] != E; i++) 
  65.      /*EMPTY*/;
  66.     if (i & 1) abort();
  67.     p->length = i/2;
  68.   }
  69.   for (i = 0; i < 256; i++) 
  70.       {
  71.     if (h8_opcodes_sorted[i][0]) 
  72.       p = h8_opcodes_sorted[i][0];
  73.     else h8_opcodes_sorted[i][0] = p;
  74.       }
  75. }
  76.  
  77.  
  78. unsigned int
  79. DEFUN(bfd_h8_disassemble,(addr, data, stream),
  80. bfd_vma addr AND
  81. CONST bfd_byte *data AND
  82. FILE *stream)
  83. {
  84.   /* Find the first entry in the table for this opcode */
  85.   static CONST char *regnames[] = {
  86.     "r0h","r1h","r2h","r3h","r4h","r5h","r6h","r7h",
  87.     "r0l","r1l","r2l","r3l","r4l","r5l","r6l","r7l" };
  88.  
  89.   int rs = 0;
  90.   int rd = 0;
  91.   int rdisp = 0;
  92.   int abs = 0;
  93.   struct h8_opcode **p = h8_opcodes_sorted[(unsigned)(data[0])];
  94.   struct h8_opcode *q;
  95.  
  96.   /* Find the exact opcode/arg combo */
  97.   while (*p) {
  98.     op_type *nib;
  99.     unsigned int len = 0;
  100.     q = *p++;
  101.     nib  =q->data.nib;
  102.     while (*nib != E) {
  103.       op_type looking_for = *nib;
  104.       int thisnib = data[len>>1] ;
  105.       thisnib = (len & 1) ? (thisnib & 0xf) : ((thisnib >> 4) & 0xf);
  106.       if ((int)looking_for & (int)B31) {
  107.     if (((int)thisnib & 0x8) ==0) goto fail;
  108.     looking_for = (op_type)((int)looking_for &  ~(int)B31);
  109.       }
  110.       if ((int)looking_for & (int)B30) {
  111.     if (((int)thisnib & 0x8) !=0) goto fail;
  112.     looking_for = (op_type)((int)looking_for &  ~(int)B30);
  113.       }
  114.       switch (looking_for) {
  115.       case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: 
  116.       case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15:
  117.     if ((int)looking_for != thisnib) goto fail;
  118.     break;
  119.       case ABS16SRC:
  120.       case ABS16OR8SRC:
  121.       case ABS16ORREL8SRC:
  122.       case ABS16DST:
  123.       case ABS16OR8DST:
  124.       case DISPSRC:
  125.       case DISPDST:
  126.       case IMM16:
  127.     abs = (data[len>>1]) * 256 + data[(len+2)>>1];
  128.     len+=3;
  129.     nib+=3;
  130.     break;
  131.       case DISPREG:
  132.     rdisp = thisnib; 
  133.     break;
  134.       case KBIT:
  135.     abs = thisnib == 0x8 ? 2:1;
  136.     break;
  137.       case IMM8:
  138.       case ABS8SRC:
  139.       case ABS8DST:
  140.       case MEMIND:
  141.       case DISP8:
  142.     abs= data[len>>1];
  143.     len++;
  144.     nib++;
  145.     break;
  146.       case IMM3:
  147.     abs = thisnib ;
  148.     break;
  149.       case RS8:
  150.       case RS16:
  151.       case RSINC:
  152.       case RSIND:
  153.     rs = thisnib;
  154.     break;
  155.       case RD16:
  156.       case RDDEC:
  157.       case RD8:
  158.       case RDIND:
  159.     rd = thisnib;
  160.     break;
  161.       default:
  162.     fprintf(stream, "Dont understand \n");
  163.     goto found;
  164.       }
  165.       len++;
  166.       nib++;
  167.     }
  168.     goto found;
  169.   fail: 
  170.     ;
  171.  
  172.   }
  173.   fprintf(stream, "%02x %02x        .word\tH'%x,H'%x",
  174.       data[0], data[1],
  175.       data[0], data[1]);
  176.   return 2;
  177.  found:;
  178.     { int i;
  179.  
  180.       for (i = 0; i < q->length; i++) {
  181.     fprintf(stream, "%02x ", data[i]);
  182.       }
  183.       for (; i < 6; i++) {
  184.     fprintf(stream, "   ");
  185.       }
  186.     }
  187.   fprintf(stream, "%s\t",q->name);
  188.   /* Now print out the args */
  189.     {
  190.       op_type *args = q->args.nib;
  191.       int hadone = 0;
  192.       while (*args != E) {
  193.     if (hadone)
  194.       fprintf(stream, ",");
  195.     switch ((int)(*args) & ~((int)B30|(int)B31)) {
  196.     case IMM16:
  197.     case IMM8:
  198.     case IMM3:
  199.       fprintf(stream, "#0x%x", (unsigned)abs); 
  200.       break;
  201.     case RD8:
  202.       fprintf(stream, "%s", regnames[rd]); 
  203.       break;
  204.     case RS8:
  205.       fprintf(stream, "%s",regnames[rs]);
  206.       break;
  207.     case RD16:
  208.       fprintf(stream, "r%d", rd& 0x7);
  209.       break;
  210.     case RS16:
  211.       fprintf(stream, "r%d", rs & 0x7);
  212.       break;
  213.     case RSINC:
  214.       fprintf(stream, "@r%d+", rs & 0x7);
  215.       break;
  216.     case RDDEC:
  217.       fprintf(stream, "@-r%d", rd & 0x7);
  218.       break;
  219.     case RDIND: 
  220.       fprintf(stream, "@r%d", rd & 0x7);
  221.       break;
  222.     case RSIND:
  223.       fprintf(stream, "@r%d",rs & 0x7);
  224.       break;
  225.     case ABS8SRC:
  226.     case ABS16SRC:
  227.     case ABS16OR8SRC:
  228.     case ABS16ORREL8SRC:
  229.     case ABS16OR8DST:
  230.     case ABS16DST:
  231.     case ABS8DST:
  232.       fprintf(stream, "@0x%x", (unsigned)abs);
  233.       break;
  234.     case MEMIND:
  235.       fprintf(stream, "@@%d (%x)",abs, abs);
  236.       break;
  237.     case DISP8:
  238.       fprintf(stream, ".%s%d (%x)",(char)abs>0 ? "+" :"", (char)abs,
  239.           addr + (char)abs + 2);
  240.       break;
  241.     case DISPSRC:
  242.     case DISPDST:
  243.       fprintf(stream, "@(0x%x,r%d)", abs, rdisp & 0x7); 
  244.       break;
  245.     case CCR:
  246.       fprintf(stream, "ccr"); 
  247.       break;
  248.     case KBIT:
  249.       fprintf(stream, "#%d",abs); 
  250.       break;
  251.     default:
  252.       abort();
  253.     }
  254.     hadone = 1;
  255.     args++;
  256.       }
  257.     }
  258.   return q->length;
  259. }
  260.  
  261.  
  262.  
  263. unsigned int DEFUN(print_insn_h8300,(addr, data, file),
  264. bfd_vma addr AND
  265. CONST char *data AND
  266. PTR file)
  267. {
  268.   static boolean init;
  269.   if (!init) {
  270.     bfd_h8_disassemble_init();
  271.     init= true;
  272.   }
  273.  
  274.   return   bfd_h8_disassemble(addr, (bfd_byte *)data, file);
  275. }
  276.  
  277. /* 
  278. Relocations for the H8
  279.  
  280. */
  281. static bfd_reloc_status_type 
  282. DEFUN(howto16_callback,(abfd, reloc_entry, symbol_in, data,
  283.             ignore_input_section, ignore_bfd),
  284.       bfd *abfd AND
  285.       arelent *reloc_entry AND
  286.       struct symbol_cache_entry *symbol_in AND
  287.       PTR data AND
  288.       asection *ignore_input_section AND
  289.       bfd *ignore_bfd)
  290. {
  291.   long relocation = 0;
  292.   bfd_vma addr = reloc_entry->address;
  293.   long x = bfd_get_16(abfd, (bfd_byte *)data + addr);
  294.  
  295.   HOWTO_PREPARE(relocation, symbol_in);
  296.  
  297.   x = (x + relocation + reloc_entry->addend);
  298.  
  299.   bfd_put_16(abfd, x, (bfd_byte *)data + addr);
  300.   return bfd_reloc_ok;
  301. }
  302.  
  303.  
  304. static bfd_reloc_status_type 
  305. DEFUN(howto8_callback,(abfd, reloc_entry, symbol_in, data,
  306.                ignore_input_section, ignore_bfd),
  307.       bfd *abfd AND
  308.       arelent *reloc_entry AND
  309.       struct symbol_cache_entry *symbol_in AND
  310.       PTR data AND
  311.       asection *ignore_input_section AND
  312.       bfd *ignore_bfd)
  313. {
  314.   long relocation = 0;
  315.   bfd_vma addr = reloc_entry->address;
  316.   long x = bfd_get_8(abfd, (bfd_byte *)data + addr);
  317.  
  318.   HOWTO_PREPARE(relocation, symbol_in);
  319.  
  320.   x = (x + relocation + reloc_entry->addend);
  321.  
  322.   bfd_put_8(abfd, x, (bfd_byte *)data + addr);
  323.   return bfd_reloc_ok;
  324. }
  325.  
  326.  
  327. static bfd_reloc_status_type 
  328. DEFUN(howto8_FFnn_callback,(abfd, reloc_entry, symbol_in, data,
  329.                 ignore_input_section, ignore_bfd),
  330.       bfd *abfd AND
  331.       arelent *reloc_entry AND
  332.       struct symbol_cache_entry *symbol_in AND
  333.       PTR data AND
  334.       asection *ignore_input_section AND
  335.       bfd *ignore_bfd)
  336. {
  337.   long relocation = 0;
  338.   bfd_vma addr = reloc_entry->address;
  339.  
  340.   long x = bfd_get_8(abfd, (bfd_byte *)data + addr);
  341.   abort();
  342.   HOWTO_PREPARE(relocation, symbol_in);
  343.  
  344.   x = (x + relocation + reloc_entry->addend);
  345.  
  346.   bfd_put_8(abfd, x, (bfd_byte *)data + addr);
  347.   return bfd_reloc_ok;
  348. }
  349.  
  350. static bfd_reloc_status_type 
  351. DEFUN(howto8_pcrel_callback,(abfd, reloc_entry, symbol_in, data,
  352.                  ignore_input_section, ignore_bfd),
  353.       bfd *abfd AND
  354.       arelent *reloc_entry AND
  355.       struct symbol_cache_entry *symbol_in AND
  356.       PTR data AND
  357.       asection *ignore_input_section AND
  358.       bfd *ignore_bfd)
  359. {
  360.   long relocation = 0;
  361.   bfd_vma addr = reloc_entry->address;
  362.   long x = bfd_get_8(abfd, (bfd_byte *)data + addr);
  363.   abort();
  364.   HOWTO_PREPARE(relocation, symbol_in);
  365.  
  366.   x = (x + relocation + reloc_entry->addend);
  367.  
  368.   bfd_put_8(abfd, x, (bfd_byte *)data + addr);
  369.   return bfd_reloc_ok;
  370. }
  371.  
  372.  
  373.  
  374. static reloc_howto_type howto_16
  375.   = NEWHOWTO(howto16_callback,"abs16",1,false,false);
  376. static reloc_howto_type howto_8
  377.   = NEWHOWTO(howto8_callback,"abs8",0,false,false);
  378.  
  379. static reloc_howto_type howto_8_FFnn
  380.   = NEWHOWTO(howto8_FFnn_callback,"ff00+abs8",0,false,false);
  381.  
  382. static reloc_howto_type howto_8_pcrel
  383.   = NEWHOWTO(howto8_pcrel_callback,"pcrel8",0,false,true);
  384.  
  385.  
  386. static CONST struct reloc_howto_struct *
  387. DEFUN(local_bfd_reloc_type_lookup,(arch, code),
  388.  CONST struct bfd_arch_info *arch AND
  389.  bfd_reloc_code_real_type code)
  390. {
  391.   switch (code) {
  392.   case BFD_RELOC_16:
  393.     return &howto_16;
  394.   case BFD_RELOC_8_FFnn:
  395.     return &howto_8_FFnn;
  396.   case BFD_RELOC_8:
  397.     return &howto_8;
  398.   case BFD_RELOC_8_PCREL:
  399.     return &howto_8_pcrel;
  400.   default:
  401.     return (reloc_howto_type *)NULL;
  402.   }
  403. }
  404.  
  405. int bfd_default_scan_num_mach();
  406.  
  407. static boolean 
  408. DEFUN(h8300_scan,(info, string),
  409. CONST struct bfd_arch_info *info AND
  410. CONST char *string)
  411. {
  412.   if (strcmp(string,"h8300") == 0) return true;
  413.   if (strcmp(string,"H8300") == 0) return true;
  414.   if (strcmp(string,"h8/300") == 0) return true;
  415.   if (strcmp(string,"H8/300") == 0) return true;
  416.   return false;
  417. }
  418.  
  419. static bfd_arch_info_type arch_info_struct = 
  420.   {
  421.     16,    /* 16 bits in a word */
  422.     16,    /* 16 bits in an address */
  423.     8,    /* 8 bits in a byte */
  424.     bfd_arch_h8300,
  425.     0,    /* only 1 machine */
  426.     "H8/300", /* arch_name  */
  427.     "H8/300", /* printable name */
  428.     1,
  429.     true,    /* the default machine */
  430.     bfd_default_compatible,
  431.     h8300_scan,
  432.     print_insn_h8300,
  433. /*    local_bfd_reloc_type_lookup, */
  434.     0,
  435.   };
  436.  
  437. void
  438. DEFUN_VOID(bfd_h8300_arch)
  439. {
  440.   bfd_arch_linkin(&arch_info_struct);
  441. }
  442.